package scatter.scattergenerator.rest.gen.controller;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import scatter.common.pojo.po.BasePo;
import scatter.common.rest.controller.SuperController;
import scatter.common.rest.tools.StringTool;
import scatter.common.rest.tools.ThreadContextTool;
import scatter.generator.core.CustomAutoGenerator;
import scatter.generator.core.CustomTableField;
import scatter.generator.core.CustomTableInfo;
import scatter.generator.pojo.enums.TableType;
import scatter.generator.pojo.param.GenerateSeperateParam;
import scatter.scattergenerator.pojo.gen.form.GenComponentForm;
import scatter.scattergenerator.pojo.gen.form.GenForm;
import scatter.scattergenerator.pojo.gen.form.TableInfoQueryForm;
import scatter.scattergenerator.pojo.history.po.TableGenHistory;
import scatter.scattergenerator.pojo.table.vo.TableColumnVo;
import scatter.scattergenerator.pojo.table.vo.TableVo;
import scatter.scattergenerator.rest.ScatterGeneratorConfiguration;
import scatter.scattergenerator.rest.config.service.IConfigDatasourceService;
import scatter.scattergenerator.rest.gen.ScatterTableGenerator;
import scatter.scattergenerator.rest.history.service.ITableGenHistoryService;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by yangwei
 * Created at 2021/2/24 12:45
 */
@Api(tags = "代码生成相关接口")
@RestController
@RequestMapping(ScatterGeneratorConfiguration.CONTROLLER_BASE_PATH + "/gen")
public class GenController extends SuperController {

    @Autowired
    private ScatterTableGenerator scatterGenerator;
    @Autowired
    private IConfigDatasourceService iConfigDatasourceService;

    @Autowired
    private ITableGenHistoryService iTableGenHistoryService;


    @ApiOperation("代码生成")
    @PreAuthorize("hasAuthority('scatterGenerator:gen')")
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public Boolean gen(@RequestBody @Validated GenForm form) {

        ThreadContextTool.put(ScatterTableGenerator.GEN_FORM_IN_THREAD_CONTEXT_KEY,form);

        GenerateSeperateParam generateSeperateParam = new GenerateSeperateParam();
        scatterGenerator.setMpg(null);
        String packageParent = "scatter." + scatterGenerator.componentNameConvertToNoLine(form.getComponentName());
        generateSeperateParam
                .setPojoComponentPath(StrUtil.format("/{}/{}/{}-pojo",form.getPosition(),form.getComponentName(),form.getComponentName()))
                .setRestComponentPath(StrUtil.format("/{}/{}/{}-rest",form.getPosition(),form.getComponentName(),form.getComponentName()))
                .setRestClientComponentPath(StrUtil.format("/{}/{}/{}-rest-client",form.getPosition(),form.getComponentName(),form.getComponentName()))
                .setRestClientImplComponentPath(StrUtil.format("/{}/{}/{}-rest-client-impl",form.getPosition(),form.getComponentName(),form.getComponentName()))
                .setWebPath(StrUtil.format("/{}/{}/web/pc",form.getPosition(),form.getComponentName()))


                .setEntityPackageParent(packageParent + ".pojo")
                .setPackageParent(packageParent + ".rest")
        .setAuthor(form.getAuthor())
        .setComponentName(form.getComponentName())
                .setModuleName(form.getModuleName())
        .setDeleteFile(form.getIsFileDelete())
        .setFileOverride(form.getIsFileOverride())
        .setTableName(form.getTableInfo().getTableName())
        .setTablePrefix(form.getTablePrefix())
        .setTableType(TableType.valueOf(form.getTableType()))

        ;
        // 生成 rest
        scatterGenerator.doGenerateSeperate(generateSeperateParam);
        // 生成成功，保存生成历史
        TableGenHistory tableGenHistory = new TableGenHistory();
        tableGenHistory.setTableComment(form.getTableInfo().getTableComment());
        tableGenHistory.setTableName(form.getTableInfo().getTableName());
        tableGenHistory.setTableType(form.getTableType());
        tableGenHistory.setConfigContent(toJsonStr(form));
        iTableGenHistoryService.save(tableGenHistory);
        return true;
    }
    @ApiOperation("加载表信息")
    @PreAuthorize("hasAuthority('scatterGenerator:tableInfo')")
    @GetMapping("/tableInfo")
    @ResponseStatus(HttpStatus.OK)
    public TableVo getTableInfo(TableInfoQueryForm tableInfoQueryForm) {
        DataSourceConfig dataSourceConfig =  iConfigDatasourceService.buildDataSourceConfigById(tableInfoQueryForm.getConfigDataSourceId());
        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude(tableInfoQueryForm.getTableName());



         CustomAutoGenerator customAutoGenerator = new CustomAutoGenerator();
        List<TableInfo> tableInfos = customAutoGenerator.customGetAllTableInfoList(dataSourceConfig, strategy);
        TableInfo tableInfo = tableInfos.stream().findFirst().get();

        TableVo tableVo = new TableVo();
        tableVo.setTableName(tableInfoQueryForm.getTableName());

        // 更新表注释
        tableVo.setTableComment(((CustomTableInfo) tableInfo).getCommentSimple());
        //rel表类型注释
        tableVo.setTableCommentRel1(((CustomTableInfo) tableInfo).getCommentRel1());
        tableVo.setTableCommentRel2(((CustomTableInfo) tableInfo).getCommentRel2());

        // 添加列
        List<TableColumnVo> tableColumns = new ArrayList<>(tableInfo.getFields().size());
        TableColumnVo tableColumn = null;
        List<String> ignoreColumns = Arrays.stream(ReflectUtil.getFields(BasePo.class)).map(field -> StringTool.humpToLine(field.getName())).collect(Collectors.toList());
        for (TableField field : tableInfo.getFields()) {
            if (ignoreColumns.contains(field.getColumnName())) {
                continue;
            }
            tableColumn = new TableColumnVo();
            tableColumn.setColumnName(field.getColumnName());
            tableColumn.setColumnComment(((CustomTableField) field).getCommentSimple());
            tableColumn.setIsRequired(((CustomTableField) field).isRequired());
            tableColumn.setIsUnique(((CustomTableField) field).isUnique());
            tableColumn.setIsQueryLike(((CustomTableField) field).isQueryLike());
            tableColumn.setIsOrderby(((CustomTableField) field).isOrderBy());
            tableColumn.setIsOrderbyAsc(((CustomTableField) field).isOrderByAsc());
            tableColumn.setLengthLimit(((CustomTableField) field).getLength());
            tableColumn.setFractionlengthLimit(((CustomTableField) field).getFractionLength());
            tableColumn.setIsForeignKey(((CustomTableField) field).isForeignKey());
            tableColumns.add(tableColumn);
        }
        tableVo.setTableColumns(tableColumns);
        return tableVo;
    }

    @ApiOperation("项目/组件代码生成")
    @PreAuthorize("hasAuthority('scatterGenerator:gen')")
    @PostMapping("/component")
    @ResponseStatus(HttpStatus.CREATED)
    public Boolean gen(@RequestBody @Validated GenComponentForm form) {
        new scatter.generator.component.ComponentGenerator (form.getComponentName(),form.getPosition()).generate();

        return true;
    }
}
